var fs = require('fs');
var path = require('path');
var request = require('request');
var file = path.join(__dirname, 'url.txt');

function getUrl() {
    console.log('getUrl');
    return new Promise(function(fullfil, reject) {
        fs.readFile(file, 'utf8', function(err, res) {
            fullfil(res);
        });
    }).then(function(url) {
        return url;
    });
}

function makeRequest(url) {
    console.log('makeRequest,url=' + url);
    return new Promise(function(fullfil, reject) {
        request(url, function(err, res, body) {
            fullfil(body);
        })
    }).then(function(body) {
        return body;
    });
}

function getFoo() {
    console.log('getFoo');
    return 'foo';
}

function* main() {
    console.log('main start');
    var url = yield getUrl();// .sync();
    console.log('url=' + url);

    var body = yield makeRequest(url);
    body = body.substring(0, 10);
    console.log(body);

    var foo = yield getFoo();
    console.log(foo);

    var bar = yield 1;
    console.log(bar);

    var xx = yield getUrl();
    console.log('xx=' + xx);
}

function runGen(gen) {
    var it = gen();
    var count = 0;
    var ret;

    function goNext(val) {
        console.log('\n\ngoNext count=' + (++count));
        ret = it.next(val);
        if (ret.done) {
            console.log('done');
            return;
        }

        var v = ret.value;

        if (v instanceof Promise && 'then' in v) {
            console.log('v is promise');
            v.then(goNext);
        } else if (Object.prototype.toString.call(v) === '[object Function]') {
            console.log('v is function');
            v(goNext);
        } else {
            console.log('v direct value');
            // direct value
            console.log('direct value');
            process.nextTick(goNext.bind(this, v));
        }
    }

    goNext();
}

runGen(main);